package com.example.demo.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import org.apache.log4j.Logger;

import com.example.demo.controller.ProjectController;


public class MergeFileUtils {
	
	private static Logger logger = Logger.getLogger(MergeFileUtils.class);
	
	private final static String startAddress = "A0000";
	private final static String endAddress = "AFFFF";
	private final static String programVersionAddress = "10F00";
	private final static String dataVersionAddress = "A5F00";
	
	public static Map<String, String> mergeFile(String programFilePath,String dataFilePath,String processInstanceName) {
		Map<String, String> result = new HashMap<String, String>();
		Integer startAddressInt = Integer.parseInt(startAddress, 16);
		Integer endAddressInteger = Integer.parseInt(endAddress, 16);
		File dataFile = new File(dataFilePath);
		java.text.DateFormat format = new java.text.SimpleDateFormat("yyyyMMddhhmmss");
		String currentTime = format.format(new Date());
		//上传文件名         
        String name = "LEC4AF_G6_Rep" + currentTime + ".mot" ;//上传文件的真实名称        
        String suffixName = name.substring(name.lastIndexOf("."));//获取后缀名
        String hash = Integer.toHexString(new Random().nextInt());//自定义随机数（字母+数字）作为文件名
        String fileName = hash + suffixName;     
        String writeFilePath =  dataFile.getParentFile().getParent() + File.separator + processInstanceName + File.separator + fileName;
		File writeName = null; 
		try {
			writeName = new File(writeFilePath); // 相对路径，如果没有则要建立一个新的output.txt文件
			if(!writeName.getParentFile().exists()) {
				writeName.getParentFile().mkdirs();
			}
            writeName.createNewFile(); // 创建新文件,有同名的文件的话直接覆盖
		}catch (Exception e) {
			e.printStackTrace();
		}
		
        //防止文件建立或读取失败，用catch捕捉错误并打印，也可以throw;
        //不关闭文件会导致资源的泄露，读写文件都同理
        //Java7的try-with-resources可以优雅关闭文件，异常时自动关闭文件；详细解读https://stackoverflow.com/a/12665271
        try (FileReader programReader = new FileReader(programFilePath);
             BufferedReader programBr = new BufferedReader(programReader); // 建立一个对象，它把文件内容转成计算机能读懂的语言
        	 FileReader dataReader = new FileReader(dataFilePath);
                BufferedReader dataBr = new BufferedReader(dataReader); // 建立一个对象，它把文件内容转成计算机能读懂的语言	
        		FileWriter writer = new FileWriter(writeName);
                BufferedWriter out = new BufferedWriter(writer)
        ) {
        	boolean isFirst = true;
            String line; 
            int addressLength;
            while ((line = programBr.readLine()) != null) {
            	if(line.substring(0,2).equals("S1")) {
            		addressLength = 8;
            	}else if(line.substring(0,2).equals("S2")){
            		addressLength = 10;
            	}else if(line.substring(0,2).equals("S3")){
            		addressLength = 12;
            	}else {
            		addressLength = 12;
            	}
                // 一次读入一行数据
                if(line.length() > addressLength) {//至少大于12才去判断是不是要替换的地址里
                	if(startAddressInt > Integer.parseInt(line.substring(4, addressLength),16) || Integer.parseInt(line.substring(4, addressLength),16) > endAddressInteger) {
                		out.write(line + "\r\n");//不在替换地址里才写进去
                	}else if(isFirst) {
                		isFirst = false;
                		while ((line = dataBr.readLine()) != null) {
                            // 一次读入一行数据
                            if(line.length() > addressLength) {//至少大于12才去判断是不是要替换的地址里
                            	if(startAddressInt < Integer.parseInt(line.substring(4, addressLength),16) && Integer.parseInt(line.substring(4, addressLength),16) < endAddressInteger ) {
                            		out.write(line + "\r\n");//在替换地址里才写进去
                            	}
                            }
                        }
                	}
                }else {
                	out.write(line+ "\r\n");
                }
            }          
            out.flush();
        } catch (IOException e) {
        	writeName.delete();
            e.printStackTrace();
        }
        result.put("name", name);
        result.put("path", writeFilePath);
        return result;
	}
	
	public static String findFileVersion(int type, File file){
		Integer addressInt;//开始截取的地址
		Integer length;//需要截取的长度
		String result = "";
		if(type == 1) {//1代表程序上传，截取程序版本
			addressInt = Integer.parseInt(programVersionAddress, 16);
			length = 16;
		}else {
			addressInt = Integer.parseInt(dataVersionAddress, 16);
			length = 20; 
		}
		
		 try (FileReader reader = new FileReader(file);
	          BufferedReader br = new BufferedReader(reader); 
		){
			  String line; 
	          int addressLength;
	          boolean isFirst = true;
	          while ((line = br.readLine()) != null && isFirst) {
	        	  if(line.substring(0,2).equals("S1")) {
	           		addressLength = 4;
		           	}else if(line.substring(0,2).equals("S2")){
		           		addressLength = 6;
		           	}else if(line.substring(0,2).equals("S3")){
		           		addressLength = 8;
		           	}else {
		           		addressLength = 8;
		           	}
		         if(line.length() > addressLength+4) {//至少大于12才去判断是不是要替换的地址里
		        	 if((Integer.parseInt(line.substring(4, addressLength+4),16) +  Integer.parseInt(line.substring(2, 4),16)-addressLength/2-1) > addressInt) {
		        		 if((Integer.parseInt(line.substring(4, addressLength+4),16) +  Integer.parseInt(line.substring(2, 4),16)-addressLength/2+1) > (addressInt + length)) {
		        			 result += line.substring((addressLength+4 +addressInt-Integer.parseInt(line.substring(4, addressLength+4),16)), (addressLength+4 + (length-result.length())+addressInt-Integer.parseInt(line.substring(4, addressLength+4),16)));
		        			 isFirst = false;
		        		 }else {
		        			 result = line.substring(line.length()-2-(addressInt-Integer.parseInt(line.substring(4, addressLength+4),16))*2, line.length()-2);
		        		 }
		        	 }
		         }
	        }			 
		 }catch (IOException e) {
			 e.printStackTrace();
			 logger.error(e);
		 }	
		result = Util.hexStringToString(result, 2);
		return result;
	}
	

}
